package cn.com.blueInfo.core.util;

import cn.com.blueInfo.core.manager.EncryptionKeyManager;
import cn.com.blueInfo.core.param.SecurityParam;
import cn.com.blueInfo.utils.error.JwtAuthenticationException;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtils {

    @Autowired
    private SecurityParam securityParam;

    @Autowired
    private EncryptionKeyManager encryptionKeyManager;

    // 创建JWT
    public String createToken(String username, Map<String, Object> claims) {
        if (claims == null) {
            claims = new HashMap<>();
        }

        Date now = new Date();
        Date expirationDate = new Date(now.getTime() + securityParam.getJwtExpiration() * 1000);

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expirationDate)
//                .signWith(encryptionKeyManager.getSecretKey(), SignatureAlgorithm.HS256)
                .signWith(encryptionKeyManager.getPrivateKey(), SignatureAlgorithm.RS256)
                .compact();
    }

    public Object getClaimsInfoByKey(String token, String claimsKey) {
        return parseToken(token).get(claimsKey);
    }

    // 解析JWT - 先尝试旧密钥，失败再尝试新密钥
    public Claims parseToken(String token) {
        // 如果处于密钥轮换期，先尝试用旧密钥解析
        if (encryptionKeyManager.isKeyRotating()) {
            try {
                return Jwts.parserBuilder()
                        .setSigningKey(encryptionKeyManager.getOldPublicKey())
                        .build()
                        .parseClaimsJws(token)
                        .getBody();
            } catch (Exception e) {
                // 旧密钥解析失败，尝试用新密钥
                return parseWithNewKey(token);
            }
        } else {
            // 不处于轮换期，直接用新密钥解析
            return parseWithNewKey(token);
        }
    }

    // 解析JWT
    public Claims parseWithNewKey(String token) {
        try {
            return Jwts.parserBuilder()
//                    .setSigningKey(encryptionKeyManager.getSecretKey())
                    .setSigningKey(encryptionKeyManager.getPublicKey())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            // 处理过期异常
            throw new JwtAuthenticationException("Token已过期", e);
        } catch (UnsupportedJwtException e) {
            // 处理不支持的JWT格式
            throw new JwtAuthenticationException("不支持的JWT格式", e);
        } catch (MalformedJwtException e) {
            // 处理无效的JWT
            throw new JwtAuthenticationException("无效的JWT", e);
        } catch (SignatureException e) {
            // 处理签名验证失败
            throw new JwtAuthenticationException("JWT签名验证失败", e);
        } catch (IllegalArgumentException e) {
            // 处理非法参数
            throw new JwtAuthenticationException("JWT参数非法", e);
        }
    }

    // 从JWT中获取用户名
    public String getUsernameFromToken(String token) {
        return parseToken(token).getSubject();
    }

    // 验证JWT是否有效
    public boolean validateToken(String token) {
        try {
            parseToken(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    // 获取过期时间
    public Long getExpiration() {
        return securityParam.getJwtExpiration() * 1000;
    }

}
